package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Service
@PropertySource("classpath:/properties/images.properties") //容器动态读取指定的配置文件
public class FileServiceImpl implements FileService{

    @Value("${image.urlPath}")          //http://image.jt.com
    private String urlPath;
    @Value("${image.fileLocalDir}")     //D:/jt-images
    private String fileLocalDir;
    //图片类型集合
    private static Set<String> typeSet=new HashSet<>();//set可去重
    static {
        typeSet.add(".jpg");
        typeSet.add(".png");
        typeSet.add(".gif");
    }
    /**
     * 注意事项：
     *      1.校验是否为图片的类型            xxx.jpg/png/jpeg/gif...
     *      2.校验是否为恶意程序             宽度/高度
     *      3.采用分目录方式进行数据的存储     1.hash方式   2.时间单位（年月日 yyyy/MM/dd）
     *      4.防止文件重名。。。             UUID.jpg 几乎不重复（概率微乎其微）
     * @param uploadFile
     * @return
     */

    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        /*判断图片类型*/
        //获取图片文件名称
        String fileName=uploadFile.getOriginalFilename();  //123.jpg
        //获取图片类型
        fileName=fileName.toLowerCase();
        int index=fileName.lastIndexOf(".");
        String fileType=fileName.substring(index); //.jpg
        //判断图片类型是否正常（是否存在于类型库里）
        if (!typeSet.contains(fileType)){
            //图片类型不正常，直接终止操作
            return ImageVO.fail();
        }
        //问题2：防止恶意程序的攻击 图片（宽/高）
        try {
            /*判断图片是否正常*/
            //利用API工具BufferedImage获取了图片的对象类型
            BufferedImage bufferedImage=ImageIO.read(uploadFile.getInputStream());
            //获取图片的宽和高
            int width=bufferedImage.getWidth();
            int height=bufferedImage.getHeight();
            //通过判断图片的宽和高，判断文件是否为一个正常的图片
            if (width==0||height==0){
                return ImageVO.fail();
            }
            /**
             * 三：分目录存储 以时间为维度截串 /yyyy/MM/dd/
             */
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            String fileDir = fileLocalDir+dateDir;
            File imageFileDir = new File(fileDir);
            if (!imageFileDir.exists()){
                //动态生成多级文件目录
                imageFileDir.mkdirs();
            }
            /**
             * 四：防止文件重名，动态生成文件名称 uuid.jpg
             * uuid:32位，16进制数  （32）^16    2^128
             */
            String uuid= UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid + fileType;  //uuid.jpg
            File realFile = new File(fileDir+realFileName);

            uploadFile.transferTo(realFile);
            //如果程序一切正常
            String url=urlPath+dateDir+realFileName;
            return ImageVO.success(url, width, height);
        }catch (IOException e){
            //将检查异常简化为运行时异常
            e.printStackTrace();
            //throw new RuntimeException(e);
            return ImageVO.fail();
        }
    }
}
